package com.rpcdemo.service;

import com.alibaba.fastjson.JSON;
import com.rpcdemo.entity.Drug;
import com.rpcdemo.entity.DscStandardProduct;
import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
import org.elasticsearch.action.admin.indices.create.CreateIndexResponse;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.admin.indices.get.GetIndexRequest;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.query.IndexQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.SearchQuery;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.stream.Collectors;


@Component
public class ElasticsearchService {
    public static final Logger log = LoggerFactory.getLogger(ElasticsearchService.class);
    @Autowired
    ElasticsearchRestTemplate restTemplate;

    public boolean deleteIndex(String indexName) throws Exception {
        GetIndexRequest request = new GetIndexRequest();
        request.indices(indexName);
        boolean exists = restTemplate.getClient().indices().exists(request, RequestOptions.DEFAULT);
        if (exists) {
            log.info("索引存在");
            DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest(indexName);
            AcknowledgedResponse deleteIndexResponse = restTemplate.getClient().indices()
                    .delete(deleteIndexRequest, RequestOptions.DEFAULT);

            if (deleteIndexResponse.isAcknowledged()) {
                log.info("删除成功");
            }
            return true;
        }
        return true;
    }

    /**
     * @param indexName
     * @param mapping   mapping怎么使用,需要学习
     * @return
     * @throws Exception
     */
    public boolean createIndex(String indexName, String mapping) throws Exception {
        //创建前先调用上面的删除索引方法
        deleteIndex(indexName);
        // 创建索引
        CreateIndexRequest createIndexRequest = new CreateIndexRequest(indexName);
        createIndexRequest.settings(Settings.builder()
                .put("index.number_of_shards", 1)//指定shards
                .put("index.number_of_replicas", 0))//指定replicas
                .mapping(mapping, XContentType.JSON);//指定mapping
        CreateIndexResponse createIndexResponse = restTemplate.getClient().indices()
                .create(createIndexRequest, RequestOptions.DEFAULT);
        if (createIndexResponse.isAcknowledged()) {
            log.info("索引创建成功");
            return true;
        }
        return false;
    }

    public <T> int documents(List<DscStandardProduct> list) {
        if (CollectionUtils.isEmpty(list)) {
            return 0;
        }
        DscStandardProduct t = list.get(0);
        Document document = t.getClass().getAnnotation(Document.class);
        BulkRequest request = new BulkRequest();
        List<IndexQuery> queries = list.stream().map(item -> {
            IndexQuery query = new IndexQuery();
            query.setIndexName(document.indexName());
            query.setType(document.type());
            query.setSource(JSON.toJSONString(item));
            return query;
        }).collect(Collectors.toList());

        // bulkIndex是什么意思？
        restTemplate.bulkIndex(queries);
        return list.size();
    }

    public void query(String name, String company, String approval, String spec) {
        Drug drug = new Drug(name, company, approval, spec);
        SearchQuery query = getQuery(drug, true);
        PageRequest request = PageRequest.of(0, 1);
        query.setPageable(request);
        List<DscStandardProduct> list = restTemplate.queryForList(query, DscStandardProduct.class);

    }


    /**
     * 构造查查条件
     *
     * @param drug
     * @param specFlag
     * @return
     */
    private SearchQuery getQuery(Drug drug, Boolean specFlag) {

        BoolQueryBuilder builder = QueryBuilders.boolQuery();
        BoolQueryBuilder nameMatch = QueryBuilders.boolQuery().minimumShouldMatch(1)
                .should(QueryBuilders.matchQuery("drugName", drug.getName()))
                .should(QueryBuilders.matchQuery("productName", drug.getName()));

        BoolQueryBuilder must = QueryBuilders.boolQuery().minimumShouldMatch(2)
                .should(nameMatch)
                .should(QueryBuilders.matchQuery("company", drug.getCompany()))
                .should(QueryBuilders.matchQuery("approvalIndex", drug.getApproval()));


        builder.must(must);
        if (specFlag) {
            BoolQueryBuilder specMatch = QueryBuilders.boolQuery().minimumShouldMatch(1)
                    .should(QueryBuilders.matchQuery("specIndex", drug.getSpec()))
                    .should(QueryBuilders.matchQuery("otherSpec", drug.getSpec()));
            builder.must(specMatch);
            builder.should(QueryBuilders.termQuery("specIndex.full", drug.getSpec()))
                    .should(QueryBuilders.termQuery("otherSpec.full", drug.getSpec()));
        }
        return new NativeSearchQuery(builder);
    }
}
